<?php
// +------------------------------------------------
// | [ JWT ]
// +------------------------------------------------
// | $iss = 'rea.51dojob.com'; // 签发者
// | $sub = 'pc';              // 接收端
// | $aud = 5;                 // 接收方
// | $iat = 0;                 // 签发时间,默认:当前时间
// | $exp = 0;                 // 过期时间,默认:当前时间+过期时间
// | $token = Jwt::token($iss,$sub,$aud);
// | echo 'token:';
// | echo '<br />';
// | echo $token;
// | echo '<hr />';
// | $payload  = Jwt::decode($token);
// | echo 'payload:';
// | echo '<br />';
// | echo '<pre>';
// | print_r($payload);
// | echo '</pre>';
// | echo '<hr />';
// +------------------------------------------------

namespace extend;

class Jwt
{
    // 头部
    private static $_header    = [
        'typ' => 'JWT',    // 类型
        'alg' => 'HS256',  // 算法
    ];
    // 有效期
    private static $_expire    = 1440;
    // 密匙
    private static $_secret    = '51dojob.com';

    // 获取token
    public static function token($iss, $sub, $aud, $iat = 0, $exp = 0)
    {
        // 头部
        $header = base64_encode( json_encode(self::$_header,JSON_UNESCAPED_UNICODE) );
        // 荷载
        $payload['iss'] = $iss;
        $payload['sub'] = $sub;
        $payload['aud'] = $aud;
        $payload['iat'] = (0 === $iat) ? time() : $iat;
        $payload['exp'] = (0 === $exp) ? (time() + self::$_expire) : $exp;
        $payload        = base64_encode( json_encode($payload,JSON_UNESCAPED_UNICODE) );
        // 签名
        $signature = self::signature($header,$payload);
        // 拼接token
        $token = $header . '.' . $payload . '.' . $signature;
        return $token;
    }

    // 解密
    public static function decode($token)
    {
        // 解析token
        $arr = explode('.',$token);
        if ( !is_array($arr) || 3 != count($arr) ) return false;
        $signature = self::signature($arr[0],$arr[1]);
        if ( $arr[2] != $signature ) return false;
        // 解析载荷
        $payload = json_decode( base64_decode($arr[1]),true );
        return $payload;
    }

    // 签名
    private static function signature($header, $payload)
    {
        $alg = json_decode( base64_decode($header),true )['alg'];
        switch ( $alg ) {
            case 'HS256':
                $signature = hash_hmac('sha256',$header . '.' . $payload,self::$_secret);
                break;
            default:
                $signature = false;
                break;
        }
        return $signature;
    }
}
